package node;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;

//	import org.w3c.dom.NamedNodeMap;
//	import org.w3c.dom.Node;
import org.w3c.dom.NodeList;



public class XmlNodeStorage implements NodeStorage{

	private static void writeChild(Document d, Node n, Element c){
		
		if (n.getChildNodes().size() != 0) {
			
			for (int aa = 0; aa < n.getChildNodes().size(); aa++) {
					
					Element $aa = d.createElement("Node");
					$aa.setAttribute("Name",n.getChildNodes().get(aa).getData());
					c.appendChild($aa);
									
					writeChild(d, n.getChildNodes().get(aa), $aa);
			
				}
		}
		else {
		}
	} 
	
	public void store(Node n) {
						
			try {
	 
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	 
			// root elements
			Document doc = docBuilder.newDocument();
			
			Element rootEl = doc.createElement("Nodes");
			rootEl.setAttribute("Name", n.getData());
			doc.appendChild(rootEl);
						
			writeChild(doc, n, rootEl);
						
			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File("output.xml"));
	 
			// Output to console for testing
		//	StreamResult result = new StreamResult(System.out);
	 
			transformer.transform(source, result);
			System.out.println("Node saved in output.xml");
			
	 
		  } catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		  } catch (TransformerException tfe) {
			tfe.printStackTrace();
		  }
	}
	
	
	private static void addChild(Node n, NodeList  nl){
		
	if (nl.getLength() != 0) {
		for (int indx = 0; indx<nl.getLength(); indx++ ){
			
		//	System.out.println("Name: " + nl.item(indx).getAttributes().getNamedItem("Name").getNodeValue());
		//	System.out.println("id: " + nl.item(indx).getAttributes().getNamedItem("id"));
			
			Node $indx = new Node();
			$indx.setData(nl.item(indx).getAttributes().getNamedItem("Name").getNodeValue());
			n.getChildNodes().add($indx);
		
			addChild($indx, nl.item(indx).getChildNodes());
			
		}
	}
	else {
	}
	}
	
	
	public Node read() throws NodeStorageException{
		Node rnode;
		rnode = new Node();
		try {
			System.out.println("Node reading from input.xml"); 
			File fXmlFile = new File("input.xml");
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
		 
			doc.getDocumentElement().normalize();
			
			NodeList nodelst = doc.getFirstChild().getChildNodes();
			rnode.setData("root");
			
			addChild(rnode, nodelst);
			
		 
			
	    } catch (Exception e) {
			throw new NodeStorageException ("1st:File input.xml not Found:", e);
		    }
		return rnode;
	}
}
